home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / grafica / amhelios / ray_rad.cpp < prev    next >
C/C++ Source or Header  |  1999-01-01  |  7KB  |  224 lines

  1. ////////////////////////////////////////////////////////////
  2. //
  3. //  RAY_RAD.CPP - Ray Casting Radiosity Class
  4. //
  5. //  Version:    1.03A
  6. //
  7. //  History:    94/08/23 - Version 1.00A release.
  8. //              94/09/24 - Modified Open function.
  9. //              94/11/24 - Modified Calculate and AddAmbient
  10. //                         functions.
  11. //              94/12/16 - Version 1.01A release.
  12. //              95/02/05 - Version 1.02A release.
  13. //              95/07/16 - Removed ambient exitance addition
  14. //                         from Calculate function.
  15. //              95/07/21 - Version 1.02B release.
  16. //              96/02/14 - Version 1.02C release.
  17. //              96/04/01 - Version 1.03A release.
  18. //
  19. //  Compilers:  Microsoft Visual C/C++ Professional V1.5
  20. //              Borland C++ Version 4.5
  21. //
  22. //  Author:     Ian Ashdown, P.Eng.
  23. //              byHeart Software Limited
  24. //              620 Ballantree Road
  25. //              West Vancouver, B.C.
  26. //              Canada V7S 1W3
  27. //              Tel. (604) 922-6148
  28. //              Fax. (604) 987-7621
  29. //
  30. //  Copyright 1994-1996 byHeart Software Limited
  31. //
  32. //  The following source code has been derived from:
  33. //
  34. //    Ashdown, I. 1994. Radiosity: A Programmer's
  35. //    Perspective. New York, NY: John Wiley & Sons.
  36. //
  37. //  It may be freely copied, redistributed, and/or modified
  38. //  for personal use ONLY, as long as the copyright notice
  39. //  is included with all source code files.
  40. //
  41. ////////////////////////////////////////////////////////////
  42.  
  43. #include "ray_rad.h"
  44.  
  45. // Open ray casting radiosity renderer
  46. BOOL RayRad::Open( Environ *pe )
  47. {
  48.   penv = pe;            // Save environment pointer
  49.   step_count = 0;       // Reset step count
  50.   convergence = 1.0;    // Convergence
  51.   start = clock();      // Initialize start time
  52.   InitExitance();       // Initialize exitances
  53.  
  54.   if (amb_flag == TRUE) // Ambient exitance required ?
  55.   {
  56.     CalcInterReflect(); // Calculate interreflection factor
  57.     CalcAmbient();      // Calculate initial ambient term
  58.   }
  59.  
  60.   return TRUE;
  61.  
  62. // Calculate element exitances
  63. BOOL RayRad::Calculate()
  64. {
  65.   int i;                // Loop index
  66.   int num_vert;         // Number of element vertices
  67.   float vsff;           // Vertex-to-source form factor
  68.   BOOL self;            // Self patch flag
  69.   Element3 *pelem;      // Element pointer
  70.   Instance *pinst;      // Instance pointer
  71.   Patch3 *ppatch;       // Patch pointer
  72.   Surface3 *psurf;      // Surface pointer
  73.   Spectra p_delta;      // Patch delta exitance
  74.   Spectra v_delta;      // Vertex delta exitance
  75.   Spectra reflect;      // Surface reflectance
  76.   Spectra shoot;        // Shoot exitance
  77.   Vertex3 *pvert;       // Vertex pointer
  78.  
  79.   // Check for maximum number of steps
  80.   if (step_count >= max_step)
  81.     return TRUE;
  82.  
  83.   UpdateUnsentStats();  // Update unsent flux statistics
  84.  
  85.   // Check for convergence
  86.   if (convergence < stop_criterion)
  87.     return TRUE;
  88.  
  89.   // Initialize form factor determination object
  90.   ffd.Init(pmax);
  91.  
  92.   // Walk the instance list
  93.   pinst = penv->GetInstPtr();
  94.   while (pinst != NULL)
  95.   {
  96.     // Walk the surface list
  97.     psurf = pinst->GetSurfPtr();
  98.     while (psurf != NULL)
  99.     {
  100.       // Get surface reflectance
  101.       reflect = psurf->GetReflectance();
  102.  
  103.       // Walk the patch list
  104.       ppatch = psurf->GetPatchPtr();
  105.       while (ppatch != NULL)
  106.       {
  107.         // Check for self patch
  108.         self = (ppatch == pmax) ? TRUE : FALSE;
  109.  
  110.         // Walk the element list
  111.         pelem = ppatch->GetElementPtr();
  112.         while (pelem != NULL)
  113.         {
  114.           if (self == FALSE)    // Ignore self
  115.           {
  116.             // Get shooting patch unsent exitance
  117.             shoot = pmax->GetExitance();
  118.  
  119.             // Reset patch delta exitance
  120.             p_delta.Reset();
  121.  
  122.             num_vert = pelem->GetNumVert();
  123.             for (i = 0; i < num_vert; i++)
  124.             {
  125.               // Get element vertex pointer
  126.               pvert = pelem->GetVertexPtr(i);
  127.  
  128.               // Get vertex-to-source form factor
  129.               if ((vsff = (float) ffd.CalcFormFactor(pvert,
  130.                   penv->GetInstPtr())) > 0.0)
  131.               {
  132.                 // Calculate vertex delta exitance
  133.                 v_delta = Mult(reflect, shoot);
  134.                 v_delta.Scale(vsff);
  135.  
  136.                 // Update vertex exitance
  137.                 pvert->GetExitance().Add(v_delta);
  138.  
  139.                 // Update patch delta exitance
  140.                 p_delta.Add(v_delta);
  141.               }
  142.             }
  143.  
  144.             // Update patch unsent exitance
  145.             p_delta.Scale(pelem->GetArea() / ((double)
  146.                 num_vert * ppatch->GetArea()));
  147.             ppatch->GetExitance().Add(p_delta);
  148.           }
  149.           pelem = pelem->GetNext();
  150.         }
  151.         ppatch = ppatch->GetNext();
  152.       }
  153.       psurf = psurf->GetNext();
  154.     }
  155.     pinst = pinst->GetNext();
  156.   }
  157.  
  158.   // Reset unsent exitance to zero
  159.   pmax->GetExitance().Reset();
  160.  
  161.   if (amb_flag == TRUE)
  162.   {
  163.     CalcAmbient();      // Recalculate ambient exitance
  164.   }
  165.  
  166.   step_count++;         // Increment step count
  167.   return FALSE;         // Convergence not achieved yet
  168. }
  169.  
  170. void RayRad::AddAmbient()       // Add ambient exitance
  171. {
  172.   int i;                // Loop index
  173.   int num_vert;         // Number of element vertices
  174.   Element3 *pelem;      // Element pointer
  175.   Instance *pinst;      // Instance pointer
  176.   Patch3 *ppatch;       // Patch pointer
  177.   Spectra delta_amb;    // Delta ambient exitance
  178.   Spectra reflect;      // Surface reflectance
  179.   Surface3 *psurf;      // Surface pointer
  180.   Vertex3 *pvert;       // Vertex pointer
  181.  
  182.   // Walk the instance list
  183.   pinst = penv->GetInstPtr();
  184.   while (pinst != NULL)
  185.   {
  186.     // Walk the surface list
  187.     psurf = pinst->GetSurfPtr();
  188.     while (psurf != NULL)
  189.     {
  190.       // Get surface reflectance
  191.       reflect = psurf->GetReflectance();
  192.  
  193.       // Walk the patch list
  194.       ppatch = psurf->GetPatchPtr();
  195.       while (ppatch != NULL)
  196.       {
  197.         // Walk the element list
  198.         pelem = ppatch->GetElementPtr();
  199.         while (pelem != NULL)
  200.         {
  201.           // Calculate delta ambient exitance
  202.           delta_amb = Mult(ambient, reflect);
  203.  
  204.           num_vert = pelem->GetNumVert();
  205.           for (i = 0; i < num_vert; i++)
  206.           {
  207.             // Get element vertex pointer
  208.             pvert = pelem->GetVertexPtr(i);
  209.  
  210.             // Update vertex exitance
  211.             pvert->GetExitance().Add(delta_amb);
  212.           }
  213.           pelem = pelem->GetNext();
  214.         }
  215.         ppatch = ppatch->GetNext();
  216.       }
  217.       psurf = psurf->GetNext();
  218.     }
  219.     pinst = pinst->GetNext();
  220.   }
  221. }
  222.  
  223.